package com.deer.wms.ASN.manage.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deer.wms.ASN.manage.dao.AsnDetailMapper;
import com.deer.wms.ASN.manage.dao.AsnMasterMapper;
import com.deer.wms.ASN.manage.model.asn.*;
import com.deer.wms.ASN.manage.model.asn.CreateASN.CreateASN;
import com.deer.wms.ASN.manage.model.asn.CreateASN.CreateASNSKUDetail;
import com.deer.wms.ASN.manage.model.asn.CreateASN.CreateASNShipDetail;
import com.deer.wms.ASN.manage.model.buy.RequestBuyDetail;
import com.deer.wms.ASN.manage.model.file.AsnDetailFile;
import com.deer.wms.ASN.manage.model.file.AsnMasterFile;
import com.deer.wms.ASN.manage.service.*;
import com.deer.wms.base.system.dao.PackDetailMapper;
import com.deer.wms.base.system.dao.SupplierManageMapper;
import com.deer.wms.base.system.model.*;
import com.deer.wms.base.system.model.Item.ItemInfo;
import com.deer.wms.base.system.service.ItemInfoService;
import com.deer.wms.busine.tactic.model.PrintTempInfo;
import com.deer.wms.busine.tactic.service.PrintTempInfoService;
import com.deer.wms.busine.tactic.service.PrintTempUtils;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.service.SuperServiceImpl;
import com.deer.wms.project.root.util.BeanUtils;
import com.deer.wms.project.root.util.DateUtils;
import com.deer.wms.project.root.util.StringUtils;
import com.deer.wms.review.manage.model.BillRecord;
import com.deer.wms.review.manage.service.BillRecordService;
import com.deer.wms.review.manage.service.CaseMasterService;
import com.deer.wms.system.manage.model.DataDictDetail;
import com.deer.wms.system.manage.model.organization.Organization;
import com.deer.wms.system.manage.model.ware.WareInfo;
import com.deer.wms.system.manage.service.DataDictDetailService;
import com.deer.wms.system.manage.service.OrganizationService;
import com.deer.wms.system.manage.service.ValidatorService;
import com.deer.wms.system.manage.service.WareInfoService;
import com.deer.wms.ware.task.model.SO.SoDetail;
import com.deer.wms.ware.task.model.SO.SoMaster;
import com.deer.wms.ware.task.model.Wave.WaveDetail;
import com.deer.wms.ware.task.model.Wave.WaveMaster;
import com.deer.wms.ware.task.service.PushErpService;
import com.deer.wms.ware.task.service.SoDetailService;
import com.deer.wms.ware.task.service.SoMasterService;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.deer.wms.project.root.util.CollectionUtils.convertMap;

/**
 * Created by guo on 2020/01/03.
 */
@Service
@Transactional
@Slf4j
public class AsnMasterServiceImpl extends SuperServiceImpl<AsnMasterMapper, AsnMaster> implements AsnMasterService {

    @Autowired
    private AsnMasterMapper asnMasterMapper;

    @Autowired
    private AsnMasterService asnMasterService;

    @Autowired
    private AsnDetailService asnDetailService;

    @Autowired
    private CaseMasterService caseMasterService;

    @Autowired
    private RequestBuyDetailService requestBuyDetailService;

    @Autowired
    private AsnMasterFileService asnMasterFileService;

    @Autowired
    private AsnDetailFileService asnDetailFileService;

    @Autowired
    private ValidatorService validatorService;

    @Autowired
    private BillRecordService billRecordService;

    @Autowired
    private WareInfoService wareInfoService;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private AsnShipDetailService asnShipDetailService;

    @Autowired
    private ItemInfoService itemInfoService;

    @Autowired
    private AsnDetailMapper asnDetailMapper;

    @Autowired
    private SupplierManageMapper supplierManageMapper;

    @Autowired
    private PackDetailMapper packDetailMapper;
    @Autowired
    private PushErpService pushErpService;

    @Autowired
    private AcceptRecordService acceptRecordService;
    @Autowired
    private SoMasterService soMasterService;
    @Autowired
    private DataDictDetailService dataDictDetailService;
    @Autowired
    private SoDetailService soDetailService;


    @Override
    public void deleteByBillNo(String billNo) {
        asnMasterMapper.deleteByBillNo(billNo);
    }

    @Override
    public void deleteByRequestBuyNo(String requestBuyBillNo) {
        asnMasterMapper.deleteByRequestBuyNo(requestBuyBillNo);

    }

    @Override
    public List<AsnMasterDto> findList(AsnMasterCriteria criteria) {
        List<AsnMasterDto> list = asnMasterMapper.findList(criteria);
        List<String> billNos = list.stream().map(item -> item.getBillNo()).collect(Collectors.toList());

        if (ObjectUtil.isEmpty(billNos)) {
          return   new ArrayList<AsnMasterDto>();
        }
        List<DataDictDetail> dataDictDetails = dataDictDetailService.list(new QueryWrapper<DataDictDetail>().eq("data_dict_code", "else"));
        Map<String, DataDictDetail> dataMap = convertMap(dataDictDetails, DataDictDetail::getDictKey);
        List<AsnDetail> asnDetails = asnDetailService.list(new QueryWrapper<AsnDetail>().in("bill_no", billNos));
        Map<String, AsnDetail> asnDetailMap = convertMap(asnDetails, AsnDetail::getBillNo);

        for (AsnMasterDto asnMasterDto : list) {
            DataDictDetail dataDictDetail = dataMap.get(Convert.toStr(asnMasterDto.getCategoryId()));
            AsnDetail asnDetail = asnDetailMap.get(asnMasterDto.getBillNo());
            if (ObjectUtil.isNotEmpty(asnDetail)) {
                asnMasterDto.setItemName(asnDetailMap.get(asnMasterDto.getBillNo()).getItemName());
            }


            if (ObjectUtil.isNotEmpty(dataDictDetail)) {
                asnMasterDto.setCategoryName(dataDictDetail.getDictValue());
            }
        }
        return list;
    }

    @Override
    public List<AsnMasterDto> findPdaList(AsnMasterCriteria criteria) {
        return asnMasterMapper.findPdaList(criteria);
    }


    @Override
    public void createAsnMaster(AsnData asnData, CurrentUser currentUser) {

        AsnMaster asnMaster = asnData.getAsnMaster();
        String tableName = "asn_master";
        Integer nextId = validatorService.getNextId(tableName);
        String billNo = asnMaster.getBillNo();
        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        //0-等待审核 1-审核通过 -1-审核退回
        Integer state = 2;

        //调拨生成
        if (asnData.getBillSource() == 4) {
            BillRecord billRecord2 = billRecordService.findByBillNoAndType(asnMaster.getAllotBillNo(), 41);//生成ASN

            billRecordService.updateBillRecord(billRecord2, currentUser);
        }
        //采购生成
        if (asnData.getBillSource() == 0 || asnData.getBillSource() == 2) {
            BillRecord billRecord2 = billRecordService.findByBillNoAndType(asnMaster.getRequestBuyBillNo(), 10);//生成ASN
            billRecordService.updateBillRecord(billRecord2, currentUser);
        }

        //新增Master
        asnMaster.setCreateUserId(createUserId);
        asnMaster.setCreateUserName(createUserName);
        asnMaster.setState(state);
        asnMaster.setInsertType(asnData.getInsertType());
        asnMaster.setBillSource(asnData.getBillSource());

            asnMasterService.saveOrUpdate(asnMaster);



        //新增detail
        List<AsnDetail> asnDetails = asnData.getAsnDetails();
        for (int i = 0; i < asnDetails.size(); i++) {
            String detailNo = billNo + "-" + (i + 1);
            AsnDetail asnDetail = asnDetails.get(i);
            asnDetail.setBillNo(billNo);
            asnDetail.setId(null);
            asnDetail.setDetailNo(detailNo);
            asnDetailService.save(asnDetail);
            //更新采购单的ASN数量
            String requestDetailDetailNo = asnDetail.getRequestDetailDetailNo();
            RequestBuyDetail requestBuyDetail = requestBuyDetailService.findByDetailNo(requestDetailDetailNo);
            if (requestBuyDetail != null) {
                requestBuyDetail.setAsnQuantity(asnDetail.getExpectQuantity() + requestBuyDetail.getAsnQuantity());
                requestBuyDetailService.updateById(requestBuyDetail);
            }
        }
         //创建拣货任务
        if (asnMaster.getAsnType() == 41) {
        acceptRecordService.pdaBatchAccept(asnMaster, currentUser);
        }


    }


    /**
     * 归档
     *
     * @param billNo
     * @param currentUser
     */
    @Override
    public void createFile(String billNo, CurrentUser currentUser) {
        AsnMaster asnMaster = asnMasterService.findBy("bill_no", billNo);
        //状态为 ASN完成状态
        if (asnMaster.getAsnState() != 3) {
            throw new ServiceException(CommonCode.ASN_FILE_ERROR);
        }
        Integer fileUserId = currentUser.getUserId();
        String fileUserName = currentUser.getUserName();
        String fileTime = DateUtils.getNowDateTimeString();

        BillRecord billRecord = new BillRecord();
        billRecord.setBillNo(billNo);
        billRecord.setRecordType(6);//ASN归档
        billRecord.setCreateTime(fileTime);
        billRecord.setCreateUserId(fileUserId);
        billRecord.setCreateUserName(fileUserName);
        billRecordService.save(billRecord);
        AsnMasterFile asnMasterFile = new AsnMasterFile();
        BeanUtils.copyProperties(asnMaster, asnMasterFile);

        asnMasterFile.setFileUserId(fileUserId);
        asnMasterFile.setFileUserName(fileUserName);
        asnMasterFile.setFileTime(fileTime);
        asnMasterFileService.save(asnMasterFile);
        List<AsnDetail> asnDetails = asnDetailService.findByBillNo(billNo);

//        BeanUtils.copyProperties(asnDetails, asnDetailFile);
        for (int i = 0; i < asnDetails.size(); i++) {
            AsnDetailFile asnDetailFile = new AsnDetailFile();
            asnDetailFile.setBillNo(asnDetails.get(i).getBillNo());
            asnDetailFile.setRequestDetailDetailNo(asnDetails.get(i).getRequestDetailDetailNo());
            asnDetailFile.setDetailNo(asnDetails.get(i).getDetailNo());
            asnDetailFile.setItemCode(asnDetails.get(i).getItemCode());
            asnDetailFile.setItemName(asnDetails.get(i).getItemName());
            asnDetailFile.setPackDetailId(asnDetails.get(i).getPackDetailId());
            asnDetailFile.setPackDescribe(asnDetails.get(i).getPackDescribe());
            asnDetailFile.setAcceptQuantity(asnDetails.get(i).getAcceptQuantity());
            asnDetailFile.setExpectQuantity(asnDetails.get(i).getExpectQuantity());
            asnDetailFile.setMemo(asnDetails.get(i).getMemo());
            asnDetailFile.setAcceptTime(asnDetails.get(i).getAcceptTime());
            asnDetailFile.setState(asnDetails.get(i).getState());
            asnDetailFile.setAsnUdfDs1(asnDetails.get(i).getAsnUdfDs1());
            asnDetailFile.setAsnUdfDs2(asnDetails.get(i).getAsnUdfDs2());
            asnDetailFile.setAsnUdfDs3(asnDetails.get(i).getAsnUdfDs3());

            asnDetailFileService.save(asnDetailFile);


        }
        asnMasterService.deleteByBillNo(billNo);
        BillRecord billRecord1 = billRecordService.findByBillNoAndType(billNo, 6);//ASN归档
        billRecord1.setModifyUserId(fileUserId);
        billRecord1.setModifyUserName(fileUserName);
        billRecord1.setModifyTime(DateUtils.getNowDateTimeString());
        billRecordService.updateById(billRecord1);
    }

    @Override
    public void createASN(CreateASN createASN, CurrentUser currentUser) {
        AsnMaster asnMaster = new AsnMaster();
        String tableName = "asn_master";
        Integer nextId = validatorService.getNextId(tableName);

        String billNo = createASN.getBillNo();
        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        String createTime = DateUtils.getNowDateTimeString();

        String wareCode = createASN.getWareCode();
        String orgCode = createASN.getOrgCode();
        WareInfo wareInfo = wareInfoService.getOneByField("ware_code", wareCode);

        Organization organization = organizationService.findBy("organization_code", orgCode);

        asnMaster.setAsnState(0);
        asnMaster.setBillNo(billNo);
        asnMaster.setCreateUserId(createUserId);
        asnMaster.setCreateUserName(createUserName);
        asnMaster.setWareId(wareInfo.getWareId());
        asnMaster.setWareName(wareInfo.getWareName());
        asnMaster.setWareId(wareInfo.getWareId());
        asnMaster.setWareCode(wareInfo.getWareCode());
        asnMaster.setOrganizationCode(organization.getOrganizationCode());
        asnMaster.setOrganizationName(organization.getOrganizationName());
        asnMaster.setOrganizationId(organization.getOrganizationId());
        asnMaster.setRequestBuyBillNo(createASN.getBillNo());
        asnMaster.setInsertType(4);
        asnMasterService.save(asnMaster);
        List<CreateASNShipDetail> shipDetails = createASN.getShipList();
        if (shipDetails != null) {
            for (CreateASNShipDetail createASNShipDetail : shipDetails
            ) {
                AsnShipDetail asnShipDetail = asnShipDetailService.findBy("ship_bill_code", createASNShipDetail.getShipBillCode());
                if (asnShipDetail == null) {
                    asnShipDetail = new AsnShipDetail();
                    asnShipDetail.setBillNo(asnMaster.getBillNo());
                    asnShipDetail.setShipBillCode(createASNShipDetail.getShipBillCode());
                    asnShipDetail.setShipCode(createASNShipDetail.getShipCode());
                    asnShipDetailService.save(asnShipDetail);
                } else {

                }
            }
        }
        List<CreateASNSKUDetail> asnskuDetails = createASN.getSkuList();
        for (int i = 0; i < asnskuDetails.size(); i++) {
            CreateASNSKUDetail createASNSKUDetail = asnskuDetails.get(i);

            ItemInfo itemInfo = itemInfoService.findBy("item_code", createASNSKUDetail.getSkuCode());
            if (itemInfo == null) {
                itemInfo = new ItemInfo();
                itemInfo.setItemCode(createASNSKUDetail.getSkuCode());
                itemInfo.setItemName(createASNSKUDetail.getSkuName());
                itemInfo.setImgUrl(createASNSKUDetail.getImgUrl());
                itemInfo.setOrganizationId(organization.getOrganizationId());
                itemInfo.setPackCode("sys_pack");
                itemInfoService.save(itemInfo);
            } else if (itemInfo.getImgUrl() == null || itemInfo.getImgUrl().equals("")) {
                itemInfo.setImgUrl(createASNSKUDetail.getImgUrl());
                itemInfoService.updateById(itemInfo);
            }
            AsnDetail asnDetail = new AsnDetail();
            asnDetail.setBillNo(asnMaster.getBillNo());
            asnDetail.setDetailNo(asnMaster.getBillNo() + (i + 1));
            asnDetail.setItemCode(createASNSKUDetail.getSkuCode());
            asnDetail.setItemName(createASNSKUDetail.getSkuName());
            asnDetail.setSpec(createASNSKUDetail.getSpec());
            asnDetail.setModel(createASNSKUDetail.getModel());
            asnDetail.setImgUrl(createASNSKUDetail.getImgUrl());
            asnDetail.setPackCode("sys_pack");
            asnDetail.setPackDetailId(166);
            asnDetail.setPackDescribe("each");
            asnDetail.setTransRatio(1.0);
            asnDetail.setExpectQuantity(createASNSKUDetail.getQuantity());
            asnDetailService.save(asnDetail);

        }

    }

    @Override
    public AsnMasterDto findByBillNo(String billNo) {
        return asnMasterMapper.findByBillNo(billNo);
    }

    @Override
    public AsnMaster findSoByBillNo(String billNo, String wareCode) {
        return asnMasterMapper.findSoByBillNo(billNo, wareCode);
    }

    @Override
    public AsnMaster findBy(String field, String value) {
        QueryWrapper<AsnMaster> qw = new QueryWrapper<>();
        return getOne(qw.eq(field, value));
    }

    @Override
    @Transactional
    public void savePurchaseOrder(Map<String, Object> map) {
        List<PurchaseOrderBO> po = pushErpService.GetAllIMInSourceBills(map);
        saveBathErp(po);

    }


    public void saveBathErp(List<PurchaseOrderBO> po) {
        if (ObjectUtil.isEmpty(po)) {
            return;
        }
        //单号
        Set<String> billNos = po.stream().map(PurchaseOrderBO::getBillNo).collect(Collectors.toSet());
        List<AsnMaster> oldAsnMaster = asnMasterService.list(new QueryWrapper<AsnMaster>().in("bill_no", billNos));

//        this.updateOrder(oldAsnMaster, po);

        Map<String, AsnMaster> asnMap = oldAsnMaster.stream().collect(Collectors.toMap(AsnMaster::getBillNo, asnMaster -> asnMaster, (oldValue, newValue) -> newValue));
        if (ObjectUtil.isNotEmpty(po)) {
            Integer wareId = 285;
            List<WareInfo> wareInfoList = wareInfoService.list();
            Map<Integer, WareInfo> wareMap = wareInfoList.stream().collect(Collectors.toMap(WareInfo::getWareId, item -> item, (oldValue, newValue) -> newValue));
            List<AsnDetail> asnDetails = new ArrayList<>();
            List<AsnMaster> asnMasters = new ArrayList<>();
            List<ItemInfo> itemInfos = new ArrayList<>();
            for (PurchaseOrderBO bo : po) {
                if (ObjectUtil.isEmpty(asnMap.get(bo.getBillNo()))) {
                    AsnMaster asnMaster = new AsnMaster();
                    //仓库id
                    asnMaster.setWareId(wareId); //仓库id
                    asnMaster.setWareCode(wareMap.get(wareId).getWareCode()); //仓库编码
                    asnMaster.setWareName(wareMap.get(wareId).getWareName()); //仓库名称
                    asnMaster.setOrganizationId(-1);
                    asnMaster.setOrganizationName("自有");
                    asnMaster.setOrganizationCode("SYS_MINE");
                    asnMaster.setBillSource(0);
                    asnMaster.setBeforeNum(bo.getId()); //源单id
                    asnMaster.setBillType(bo.getBillTypeId());//单据类型ID
                    asnMaster.setUda1(bo.getBillTypeName());//单据类型
                    asnMaster.setBillNo(bo.getBillNo());//单据编号
                    asnMaster.setExpectTime(bo.getBillDate());//单据日期
                    asnMaster.setAsnState(0);//工业单据状态
                    asnMaster.setSupplierId(bo.getSupplierId());//供应商ID
                    asnMaster.setSupplierName(bo.getSupplierName());//供应商名称
                    asnMaster.setCreateUserId(bo.getCustomerId());//客户ID
                    asnMaster.setAsnUdfHs2(bo.getCustomerName());//客户名称
                    asnMaster.setDeptId(bo.getDeptId());//部门ID
                    asnMaster.setUda3(bo.getDeptName());//部门名称
                    asnMaster.setMemo(bo.getRemark());//备注
                    asnMaster.setAgreementNo(bo.getDetails().iterator().next().getAgreementNo()); //履约号
                    asnMaster.setAsnType(bo.getDetails().iterator().next().getTargetBillTypeId()); //入库单类型1,2,5,10,41
                    List<PurchaseOrderDetailBO> purchaseOrderDetailBOS = bo.getDetails();
                    Integer i = 1;
                    for (PurchaseOrderDetailBO purchaseOrderDetailBO : purchaseOrderDetailBOS) {
                        AsnDetail asnDetail = new AsnDetail();
                        asnDetail.setBillNo(asnMaster.getBillNo());//ASN单号
                        asnDetail.setPackDetailId(33469);//基本单位ID
                        asnDetail.setPackDescribe(purchaseOrderDetailBO.getUnitName());//单位
                        asnDetail.setExpectPackDetailId(purchaseOrderDetailBO.getItemId());//物料ID
                        asnDetail.setItemCode(purchaseOrderDetailBO.getItemNumber());//物料编码
                        asnDetail.setItemName(purchaseOrderDetailBO.getItemName());//物料名称
                        asnDetail.setSourceId(bo.getId());
                        asnDetail.setUda1(purchaseOrderDetailBO.getItemModel());//规格型号
                        asnDetail.setAcceptPackDetailId(purchaseOrderDetailBO.getAuxPropClassId());//辅助属性类别ID
                        asnDetail.setUpperPackDetailId(purchaseOrderDetailBO.getAuxPropId());//辅助属性ID
                        asnDetail.setAsnUdfDs1(purchaseOrderDetailBO.getAuxPropName());//辅助属性
                        asnDetail.setDetailNo(asnMaster.getBillNo() + "-" + i);
                        asnDetail.setStockId(purchaseOrderDetailBO.getStockId());  //仓库id
                        asnDetail.setStockName(purchaseOrderDetailBO.getStockName()); //仓库名称
                        asnDetail.setMemo(purchaseOrderDetailBO.getRemark());
                        asnDetail.setUda2(purchaseOrderDetailBO.getBatchManager() == null || purchaseOrderDetailBO.getBatchManager() == false ? "0" : "1");
                        asnDetail.setErpBatch(purchaseOrderDetailBO.getBatchNo());//批号
//                                    asnDetail.setTransRatio(purchaseOrderDetailBO.getAuxQty());//数量
                        if (bo.getBillTypeId() == 702) {
                            asnDetail.setExpectQuantity(purchaseOrderDetailBO.getQcQty());//待检数量,为全部数量
                            ItemInfo itemInfo = itemInfoService.getOneByField("item_code", purchaseOrderDetailBO.getItemNumber());
                            if (ObjectUtil.isNotNull(itemInfo) && !"SYS-CHECK".equals(itemInfo.getQcTacticCode())) {
                                itemInfo.setQcTacticCode("SYS-CHECK");
                                itemInfos.add(itemInfo);
                            }
                        } else {
                            asnDetail.setExpectQuantity(purchaseOrderDetailBO.getQty());//基本单位数量
                            asnDetail.setAcceptQuantity(purchaseOrderDetailBO.getQcQty());//基本单位待检数量
                        }
                        asnDetail.setRowIndex(purchaseOrderDetailBO.getRowIndex());//行号

                        asnDetail.setPackCode(purchaseOrderDetailBO.getMtoNo());//计划跟踪号

                        //目标单据红蓝字
                        asnDetail.setExpectPackDescribe(purchaseOrderDetailBO.getTargetBillROB() == null || purchaseOrderDetailBO.getBatchManager() == false ? "0" : "1");
                        asnDetail.setUpperPackDescribe(purchaseOrderDetailBO.getTargetBillTypeId().toString());
                        asnDetail.setAcceptPackDescribe(purchaseOrderDetailBO.getShelfLifeManager() == null || purchaseOrderDetailBO.getShelfLifeManager() == false ? "0" : "1");
//                        asnDetail.setAsnUdfDs2(purchaseOrderDetailBO.getProductionDate());
//                        asnDetail.setAsnUdfDs3(purchaseOrderDetailBO.getShelfLifeDays().toString());
                        asnDetail.setVersion(purchaseOrderDetailBO.getVersion());
                        asnDetail.setLatestVersion(purchaseOrderDetailBO.getLatestVersion());
                        i++;
                        asnDetails.add(asnDetail);
                    }
                    asnMasters.add(asnMaster);
                }

            }
            Set<String> detailNos = asnDetails.stream().map(item -> item.getDetailNo()).collect(Collectors.toSet());
            if (ObjectUtil.isEmpty(detailNos)) {
                return;
            }
            List<AsnDetail> oldDetailS = asnDetailService.list(new QueryWrapper<AsnDetail>().in("detail_no", detailNos));
            Set<String> oldDetailNos = oldDetailS.stream().map(item -> item.getDetailNo()).collect(Collectors.toSet());

            List<AsnDetail> asnDetailList = asnDetails.stream().filter(item -> !oldDetailNos.contains(item.getDetailNo())).collect(Collectors.toList());

            asnMasterService.saveBatch(asnMasters);

            asnDetailService.saveBatch(asnDetailList);

            if (itemInfos.size() != 0) {
                itemInfoService.saveOrUpdateBatch(itemInfos);
            }
        }


    }




    public void updateOrder(List<AsnMaster> orderAsn, List<PurchaseOrderBO> po) {
        Map<String, List<AsnMaster>> map = orderAsn.stream().collect(Collectors.groupingBy(AsnMaster::getBillNo));
        for (PurchaseOrderBO billOutBO : po) {
            List<AsnMaster> asnMasters = map.get(billOutBO.getBillNo());
            if (ObjectUtil.isEmpty(asnMasters)) {
                continue;
            }
            if (asnMasters.size() > 1) {
                Set<Integer> ids = asnMasters.stream().map(AsnMaster::getId).collect(Collectors.toSet());
                Set<String> billNos = asnMasters.stream().map(AsnMaster::getBillNo).collect(Collectors.toSet());
                asnDetailService.remove(new QueryWrapper<AsnDetail>().in("bill_no", billNos));
                asnMasterService.removeByIds(ids);
                log.info("删除单号{}，原单{} ",billNos);
            }
            AsnMaster next = asnMasters.iterator().next();
            //如果原单跟新单子不相等，删除原单
            if (!billOutBO.getId().equals(next.getBeforeNum())) {
                //删除原单
                asnDetailService.remove(new QueryWrapper<AsnDetail>().eq("bill_no", next.getBillNo()));
                asnMasterService.removeById(next.getId());
                log.info("删除单号{}，原单{} ",next.getBillNo(),next.getBeforeNum());
            }

        }
    }
    @Override
    public void createAsnMaster2(AsnData asnData, CurrentUser currentUser) {
        AsnMaster asnMaster = asnData.getAsnMaster();
        String tableName = "asn_master";
        Integer nextId = validatorService.getNextId(tableName);

        String billNo = "ASN" + "-" + nextId;
        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        //0-等待审核 1-审核通过 -1-审核退回
        Integer state = 2;

        //调拨生成
        if (asnData.getBillSource() == 4) {
            BillRecord billRecord2 = billRecordService.findByBillNoAndType(asnMaster.getAllotBillNo(), 41);//生成ASN

            billRecordService.updateBillRecord(billRecord2, currentUser);
        }
        //采购生成
        if (asnData.getBillSource() == 0 || asnData.getBillSource() == 2) {
            BillRecord billRecord2 = billRecordService.findByBillNoAndType(asnMaster.getRequestBuyBillNo(), 10);//生成ASN
            billRecordService.updateBillRecord(billRecord2, currentUser);
        }

        //新增Master
        asnMaster.setCreateUserId(createUserId);
        asnMaster.setCreateUserName(createUserName);
        asnMaster.setState(state);
        asnMaster.setInsertType(asnData.getInsertType());
        asnMaster.setBillSource(asnData.getBillSource());
        asnMaster.setAsnUdfHs1("1");//标记先发配件入库任务字段
        if (StringUtils.isNotEmpty(asnMaster.getBillNo())) {
            asnMasterService.updateById(asnMaster);
        } else {
            asnMaster.setBillNo(billNo);
            asnMasterService.save(asnMaster);
        }


        //新增detail
        List<AsnDetail> asnDetails = asnData.getAsnDetails();
        for (int i = 0; i < asnDetails.size(); i++) {
            String detailNo = billNo + "-" + (i + 1);
            AsnDetail asnDetail = asnDetails.get(i);
            asnDetail.setBillNo(billNo);
            asnDetail.setId(null);
            asnDetail.setDetailNo(detailNo);
            asnDetailService.save(asnDetail);
            //更新采购单的ASN数量
            String requestDetailDetailNo = asnDetail.getRequestDetailDetailNo();
            RequestBuyDetail requestBuyDetail = requestBuyDetailService.findByDetailNo(requestDetailDetailNo);
            if (requestBuyDetail != null) {
                requestBuyDetail.setAsnQuantity(asnDetail.getExpectQuantity() + requestBuyDetail.getAsnQuantity());
                requestBuyDetailService.updateById(requestBuyDetail);
            }
        }

    }



    @Override
    public List<AsnMasterDto> findList2(AsnMasterCriteria criteria) {
        return asnMasterMapper.findList2(criteria);
    }

    @Override
    public List<AsnMasterDto> findQcList(AsnMasterCriteria criteria) {
        return asnMasterMapper.findQcList(criteria);
    }

    @Override
    public void updateQcState(String billNo, int qcState) {
        asnMasterMapper.updateQcState(billNo, qcState);
    }

    /**
     * 出库单据到入库
     *
     * @param
     */
    @Override
    public void saveOrder(List<BillOutBO> boList) {
        List<PurchaseOrderBO> po = new ArrayList<>();
        boList.forEach(item -> {
            PurchaseOrderBO purchaseOrderBO = new PurchaseOrderBO();
            BeanUtils.copyProperties(item, purchaseOrderBO);
            List<BillOutDetailBO> details = item.getDetails();
            List<PurchaseOrderDetailBO> detailBOS = new ArrayList<>();
            for (BillOutDetailBO detail : details) {
                PurchaseOrderDetailBO purchaseOrderDetailBO = new PurchaseOrderDetailBO();
                BeanUtils.copyProperties(detail, purchaseOrderDetailBO);
                detailBOS.add(purchaseOrderDetailBO);
            }
            purchaseOrderBO.setDetails(detailBOS);
            po.add(purchaseOrderBO);
        });
        saveBathErp(po);

    }

    /**
     * 回传ERP事务
     *
     * @param asnMaster
     * @param cellCode
     * @param currentUser
     */
    @Override
    public void accomplish(AsnMaster asnMaster, String cellCode, CurrentUser currentUser) {
        //step0上架指定货位
        acceptRecordService.createByAsnDetail(asnMaster, cellCode, currentUser);

    }

    @Override
    public AsnMaster erpByBillNo(Map<String, Object> map) {
        PurchaseOrderBO bo = pushErpService.erpByBillNo(map);
        Integer wareId = 285;
        List<WareInfo> wareInfoList = wareInfoService.list();
        Map<Integer, WareInfo> wareMap = wareInfoList.stream().collect(Collectors.toMap(WareInfo::getWareId, item -> item, (oldValue, newValue) -> newValue));
        List<AsnDetail> asnDetails = new ArrayList<>();
        List<ItemInfo> itemInfos = new ArrayList<>();
        AsnMaster asnMaster = new AsnMaster();
        //仓库id
        asnMaster.setWareId(wareId); //仓库id
        asnMaster.setWareCode(wareMap.get(wareId).getWareCode()); //仓库编码
        asnMaster.setWareName(wareMap.get(wareId).getWareName()); //仓库名称
        asnMaster.setOrganizationId(-1);
        asnMaster.setOrganizationName("自有");
        asnMaster.setOrganizationCode("SYS_MINE");
        asnMaster.setBillSource(0);
        asnMaster.setBeforeNum(bo.getId()); //源单id
        asnMaster.setBillType(bo.getBillTypeId());//单据类型ID
        asnMaster.setUda1(bo.getBillTypeName());//单据类型
        asnMaster.setBillNo(bo.getBillNo());//单据编号
        asnMaster.setExpectTime(bo.getBillDate());//单据日期
        asnMaster.setAsnState(0);//工业单据状态
        asnMaster.setUda2(bo.getBillClosed() == null || bo.getBillClosed() == false ? "0" : "1");//关闭状态
        asnMaster.setSupplierId(bo.getSupplierId());//供应商ID
        asnMaster.setSupplierName(bo.getSupplierName());//供应商名称
        asnMaster.setCreateUserId(bo.getCustomerId());//客户ID
        asnMaster.setAsnUdfHs2(bo.getCustomerName());//客户名称
        asnMaster.setModifyUserId(bo.getDeptId());//部门ID
        asnMaster.setUda3(bo.getDeptName());//部门名称
        asnMaster.setMemo(bo.getRemark());//备注
        asnMaster.setAgreementNo(bo.getDetails().iterator().next().getAgreementNo()); //履约号
        asnMaster.setAsnType(bo.getDetails().iterator().next().getTargetBillTypeId()); //入库单类型1,2,5,10,41
        List<PurchaseOrderDetailBO> purchaseOrderDetailBOS = bo.getDetails();
        Integer i = 1;
        for (PurchaseOrderDetailBO purchaseOrderDetailBO : purchaseOrderDetailBOS) {
            AsnDetail asnDetail = new AsnDetail();
            asnDetail.setBillNo(asnMaster.getBillNo());//ASN单号
            asnDetail.setPackDetailId(33469);//基本单位ID
            asnDetail.setPackDescribe(purchaseOrderDetailBO.getUnitName());//单位
            asnDetail.setExpectPackDetailId(purchaseOrderDetailBO.getItemId());//物料ID
            asnDetail.setItemCode(purchaseOrderDetailBO.getItemNumber());//物料编码
            asnDetail.setItemName(purchaseOrderDetailBO.getItemName());//物料名称
            asnDetail.setSourceId(bo.getId());
            asnDetail.setUda1(purchaseOrderDetailBO.getItemModel());//规格型号
            asnDetail.setAcceptPackDetailId(purchaseOrderDetailBO.getAuxPropClassId());//辅助属性类别ID
            asnDetail.setUpperPackDetailId(purchaseOrderDetailBO.getAuxPropId());//辅助属性ID
            asnDetail.setAsnUdfDs1(purchaseOrderDetailBO.getAuxPropName());//辅助属性
            asnDetail.setDetailNo(asnMaster.getBillNo() + "-" + i);
            asnDetail.setStockId(purchaseOrderDetailBO.getStockId());  //仓库id
            asnDetail.setStockName(purchaseOrderDetailBO.getStockName()); //仓库名称
            asnDetail.setMemo(purchaseOrderDetailBO.getRemark());
            asnDetail.setUda2(purchaseOrderDetailBO.getBatchManager() == null || purchaseOrderDetailBO.getBatchManager() == false ? "0" : "1");
            asnDetail.setErpBatch(purchaseOrderDetailBO.getBatchNo());//批号

                asnDetail.setExpectQuantity(purchaseOrderDetailBO.getQty());//基本单位数量
                asnDetail.setAcceptQuantity(purchaseOrderDetailBO.getQcQty());//基本单位待检数量
            asnDetail.setRowIndex(purchaseOrderDetailBO.getRowIndex());//行号

            asnDetail.setPackCode(purchaseOrderDetailBO.getMtoNo());//计划跟踪号

            //目标单据红蓝字
            asnDetail.setExpectPackDescribe(purchaseOrderDetailBO.getTargetBillROB() == null || purchaseOrderDetailBO.getBatchManager() == false ? "0" : "1");
            asnDetail.setAcceptPackDescribe(purchaseOrderDetailBO.getShelfLifeManager() == null || purchaseOrderDetailBO.getShelfLifeManager() == false ? "0" : "1");
            asnDetail.setAsnUdfDs2(purchaseOrderDetailBO.getProductionDate());
            asnDetail.setVersion(purchaseOrderDetailBO.getVersion());
            asnDetail.setLatestVersion(purchaseOrderDetailBO.getLatestVersion());
            i++;
            asnDetails.add(asnDetail);
        }
        asnMaster.setAsnDetails(asnDetails);
        return asnMaster;

    }


    @Autowired
    private PrintTempInfoService printTempInfoService;

    @Override
    public String allotPrint(String billNo, CurrentUser currentUser) {
        AsnMaster asnMaster = getOne(new QueryWrapper<AsnMaster>().eq("bill_no", billNo));
        List<AsnDetail> asnDetails = asnDetailService.list(new QueryWrapper<AsnDetail>().eq("bill_no", billNo));

        PrintTempInfo printTempInfo = printTempInfoService.findByWare(1, "快递面单");
        if (printTempInfo == null) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "未匹配到验收标签模板");
        }
        String html = printTempInfo.getTempHtml();
        Document doc = Jsoup.parse(html);
        //删除不显示的
        doc.select(".dis-none").remove();
        //直线中间蓝点的问题
        doc.select(".line-handle").remove();
//         if(inventory==null){
//            doc.select(".baokuan").remove();
//        } else if(!acceptRecord.getCellCode().equals(inventory.getCellCode())){
//             doc.select(".baokuan").remove();
//         }else  if(inventory.getBaoKuan()==0 &&  inventory.getAllotQuantity()<0.01 ){
//             doc.select(".baokuan").remove();
//         }
        doc.select(".baokuan").remove();
        doc.select(".fromAreaName").remove();
        doc.select(".toAreaName").remove();

        Elements select = doc.select(".detail");
        Element element = select.get(2);
        element.text("生产退料单");

//        Elements select = doc.select(".detail").tagName("生产退料单");

//        String acceptInfo =
//                acceptRecord.getAcceptRecordCode() + "---" + acceptRecord.getItemCode() + "---" + acceptRecord.getItemName() + "---" + itemBatch.getBatchName() + "---" + acceptRecord.getQuantity();
        PrintTempUtils.setTempData("SHIP_BILL_NO", billNo, doc, "text");
        PrintTempUtils.setTempData("SHIP_BILL_NO_BAR_CODE", billNo, doc, "qrCode");
        PrintTempUtils.setTempData("PRINT_TIME", DateUtils.getNowDateTimeString(), doc, "text");
        PrintTempUtils.setTempData("PRINT_DATE", DateUtils.getNowDateString(), doc, "text");
        PrintTempUtils.setTempData("PRINT_USER_NAME", currentUser.getUserName(), doc, "text");
        PrintTempUtils.setTempData("SO_BILL_NO", asnMaster.getOrderBillNo(), doc, "text");
        PrintTempUtils.setTempData("EXT3", asnMaster.getMemo(), doc, "text");



        if (doc.getElementById("FULL_ITEMS_DETAIL_TABLE") != null) {
            Element FULL_ITEMS_DETAIL_TABLE = doc.getElementById("FULL_ITEMS_DETAIL_TABLE");
            Element tbody = FULL_ITEMS_DETAIL_TABLE.getElementsByTag("tBody").get(0);
            Element ITEM_LIST_DETAIL = tbody.getElementById("ITEM_LIST_DETAIL");
            Integer colspan = 0;

            for (AsnDetail asnDetail : asnDetails) {
                Element newEle = ITEM_LIST_DETAIL.clone();
                ItemInfo itemInfo = itemInfoService.getOne(new QueryWrapper<ItemInfo>().eq("item_code", asnDetail.getItemCode()));
                colspan += PrintTempUtils.setTempData("ITEM_LIST_DETAIL_ITEM_CODE", asnDetail.getItemCode(), newEle, "text");
                colspan += PrintTempUtils.setTempData("ITEM_LIST_DETAIL_ITEM_NAME", asnDetail.getItemName(), newEle, "text");
                colspan += PrintTempUtils.setTempData("ITEM_LIST_DETAIL_MODEL", itemInfo.getModel(), newEle, "text");
                colspan += PrintTempUtils.setTempData("ITEM_LIST_DETAIL_QTY", asnDetail.getExpectQuantity(), newEle, "text");
                colspan += PrintTempUtils.setTempData("ITEM_LIST_DETAIL_REMAKE", "备注", newEle, "text");

                newEle.appendTo(tbody);
            }

            ITEM_LIST_DETAIL.remove();
        }


        //doc在创建时里面包含了html head body等节点  不需要
        Element labelContent = doc.getElementsByAttributeValue("class", "label-content").get(0);
        String tempHtml = labelContent.toString();

        return tempHtml;


    }

    /**
     * 同步拉取出库单子
     *
     * @param billNo
     */
    @Override
    public void synchronous(String billNo) {
        List<SoDetail> soDetailList = soDetailService.list(new QueryWrapper<SoDetail>().eq("bill_no", billNo));
        List<AsnDetail> allAsn = new ArrayList<>();
        List<AsnDetail> oldAsn = asnDetailService.list(new QueryWrapper<AsnDetail>().eq("bill_no", billNo));
        List<AsnDetail> newAsn = new ArrayList<>();
        for (SoDetail soDetail : soDetailList) {
            AsnDetail asnDetail = new AsnDetail();
            //MTo号
            asnDetail.setMtoNo(soDetail.getMergeNo());
            asnDetail.setRowIndex(soDetail.getErpBillId());
            asnDetail.setBillNo(asnDetail.getBillNo());//ASN单号
            asnDetail.setPackDetailId(33469);//基本单位ID
            asnDetail.setItemCode(soDetail.getItemCode());//物料编码
            asnDetail.setItemName(soDetail.getItemName());//物料名称
            asnDetail.setUda1(soDetail.getSoUdfDs1());//规格型号
            asnDetail.setDetailNo(String.format("%s-%s", soDetail.getBillNo(), soDetail.getBomSplit()));
            asnDetail.setExpectQuantity(soDetail.getOrderQuantity());//基本单位数量
            newAsn.add(asnDetail);
        }
        List<SoMaster> soMasters = new ArrayList<>();

        if (ObjectUtil.isEmpty(newAsn)) {
            newAsn = new ArrayList<AsnDetail>();
        }

        if (ObjectUtil.isEmpty(oldAsn)) {
            oldAsn = new ArrayList<AsnDetail>();
        }
        //对应波次详情
        //老单子新单子合并
        allAsn.addAll(oldAsn);
        allAsn.addAll(newAsn);
        //行号可能重复，不能作为唯一条件去重
        Map<String, AsnDetail> oldMap = convertMap(oldAsn, AsnDetail::getMtoNo);
        //新单子老单子合并
        Map<String, AsnDetail> newMap = convertMap(newAsn, AsnDetail::getMtoNo);
        //3.根据明细行去获取
        contrastSoDetail(allAsn,  oldMap,newMap);
    }

    /**
     * 根据任务单同步物料
     *
     * @param asnMaster
     */
    @Override
    public void synchronous(AsnMaster asnMaster) {
        List<AsnDetail> asnDetails = asnDetailService.list(new QueryWrapper<AsnDetail>().eq("bill_no", asnMaster.getBillNo()));
        Map<Integer, AsnDetail> detailMap = convertMap(asnDetails, AsnDetail::getRowIndex);
        Map<String, Object> map = new HashMap<>();
        map.put("billNo", asnMaster.getBillNo());
        map.put("billTypeId", asnMaster.getBillType());
        Map<String, AsnMaster> asnMasterMap = new HashMap<>();
        asnMasterMap.put(asnMaster.getBillNo(), asnMaster);
        asnDetailService.savePurchaseOrder(map, asnMasterMap, Collections.singletonList(asnMaster.getBillNo()));

//        List<PurchaseOrderBO> purchaseOrderBOS = pushErpService.GetAllIMInSourceBills(map);
//        if (ObjectUtil.isNotEmpty(purchaseOrderBOS)) {
//            PurchaseOrderBO bo = purchaseOrderBOS.get(0);
//            asnMaster.setOrganizationId(-1);
//            asnMaster.setOrganizationName("自有");
//            asnMaster.setOrganizationCode("SYS_MINE");
//            asnMaster.setBillSource(0);
//            asnMaster.setBeforeNum(bo.getId()); //源单id
//            asnMaster.setBillType(bo.getBillTypeId());//单据类型ID
//            asnMaster.setUda1(bo.getBillTypeName());//单据类型
//            asnMaster.setBillNo(bo.getBillNo());//单据编号
//            asnMaster.setExpectTime(bo.getBillDate());//单据日期
//            asnMaster.setAsnState(0);//工业单据状态
//            asnMaster.setSupplierId(bo.getSupplierId());//供应商ID
//            asnMaster.setSupplierName(bo.getSupplierName());//供应商名称
//            asnMaster.setCreateUserId(bo.getCustomerId());//客户ID
//            asnMaster.setAsnUdfHs2(bo.getCustomerName());//客户名称
//            asnMaster.setDeptId(bo.getDeptId());//部门ID
//            asnMaster.setUda3(bo.getDeptName());//部门名称
//            asnMaster.setMemo(bo.getRemark());//备注
//            List<PurchaseOrderDetailBO> details = bo.getDetails();
//            for (PurchaseOrderDetailBO detail : details) {
//                AsnDetail asnDetail = detailMap.get(detail.getRowIndex());
//                asnDetail.setItemName(detail.getItemName());
//                asnDetail.setItemCode(detail.getItemNumber());
//                //基本单位数量
//                asnDetail.setExpectQuantity(detail.getOriginQty());
//                //源单id
//                asnDetail.setSourceId(bo.getId());
//            }
//        }
//        //批量修改
//        asnDetailService.updateBatchById(asnDetails);
//        //批量修改
//        asnMasterService.updateById(asnMaster);
    }

    public void contrastSoDetail(List<AsnDetail> allAsn, Map<String, AsnDetail> oldMap, Map<String, AsnDetail> newMap) {
        for (AsnDetail key : allAsn) {

            AsnDetail newSd = newMap.get(key.getMtoNo());
            AsnDetail oldSd = oldMap.get(key.getMtoNo());
            if (newSd == null) {

                //如果老单子删除
                asnDetailService.removeById(oldSd.getId());

            } else if (ObjectUtil.isEmpty(oldSd)) {
                //如果老单子为空则新增一条
                newSd.setState(0);
                asnDetailService.save(newSd);
                ;
            } else {
                //都有，则判断数量，有变化则修改
                if (ObjectUtil.notEqual(oldSd.getExpectQuantity(), newSd.getExpectQuantity())) {
                    Double newQty = newSd.getExpectQuantity();
                    oldSd.setExpectQuantity(newQty);
                }
                asnDetailService.updateById(oldSd);
            }
        }
    }
}

